<template>
  <div class="building-container">
    <!-- 搜索区域 -->
    <div class="search-container">
      <div class="search-label">企业名称：</div>
      <el-input
        v-model="params.name"
        clearable
        placeholder="请输入内容"
        class="search-main"
        @clear="search"
      />
      <el-button type="primary" @click="search">查询</el-button>
    </div>
    <div class="create-container">
      <el-button
        v-permission="'park:enterprise:add_edit'"
        type="primary"
        @click="$router.push('/addEnterprise')"
        >添加企业</el-button
      >
    </div>
    <!-- 表格区域 -->
    <div class="table">
      <el-table style="width: 100%" :data="list" @expand-change="expandChange">
        <!-- 展开列 -->
        <el-table-column type="expand">
          <template #default="scope">
            <el-table :data="scope.row.rentList">
              <el-table-column label="租赁楼宇" width="320" prop="buildingName" />
              <el-table-column label="租赁起始时间" prop="startTime">
                <!-- prop无法存放多个字段（sttartTime，endTime） -->
                <!-- template #default="对象" 自定义插槽，直接拿到当前行信息 -->
                <template #default="rentObj">
                  {{ rentObj.row.startTime }} 至 {{ rentObj.row.endTime }}
                </template>
              </el-table-column>
              <el-table-column label="合同状态" prop="status">
                <template #default="rentObj">
                  <el-tag :type="formatInfoType(rentObj.row.status)">{{
                    formatStatus(rentObj.row.status)
                  }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="180">
                <template #default="rentObj">
                  <el-button
                    v-permission="'park:rent:add_surrender'"
                    size="mini"
                    type="text"
                    :disabled="rentObj.row.status === 3"
                    @click="rentingOut(rentObj.row.id)"
                    >退租</el-button
                  >
                  <el-button
                    v-permission="'park:rent:remove'"
                    size="mini"
                    type="text"
                    :disabled="rentObj.row.status !== 3"
                    @click="rentingDel(rentObj.row.id)"
                    >删除</el-button
                  >
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>
        <el-table-column type="index" label="序号" :index="indexMethod" />
        <el-table-column label="企业名称" width="320" prop="name" />
        <el-table-column label="联系人" prop="contact" />
        <el-table-column label="联系电话" prop="contactNumber" />
        <el-table-column label="操作">
          <!-- 作用于插槽接收el-table-column信息 #name="对象"  可以通过打印查看信息 -->
          <template #default="scope">
            <el-button
              v-permission="'park:rent:add_surrender'"
              size="mini"
              type="text"
              @click="openAddRent(scope.row.id)"
              >添加合同</el-button
            >
            <el-button
              v-permission="'park:enterprise:query'"
              size="mini"
              type="text"
              @click="$router.push(`/enterpriseDetail/${scope.row.id}`)"
              >查看</el-button
            >
            <el-button
              v-permission="'park:enterprise:add_edit'"
              size="mini"
              type="text"
              @click="editEnterprise(scope.row.id)"
              >编辑</el-button
            >
            <el-button
              v-permission="'park:enterprise:remove'"
              size="mini"
              type="text"
              @click="delEnterprise(scope.row.id)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- 表格翻页 -->
    <div class="page-container">
      <!-- total和page-size 必须配置 总页数=total/page-size -->
      <!-- @current-change 必须配置 切换页码 -->
      <!-- :current-page 以完善查询后页码归1 -->
      <el-pagination
        layout="total, prev, pager, next"
        :total="total"
        :page-size="params.pageSize"
        :current-page="params.page"
        @current-change="handleCurrentChange"
      />
    </div>
    <!-- 添加合同弹框 -->
    <!-- title 左上角文本 -->
    <!-- :bisible 控制弹框显示隐藏 -->
    <!-- @close 弹框关闭时 会执行的函数 -->
    <!-- :close-on-click-modal 点击模态框（遮罩） 不关闭弹窗 -->
    <el-dialog
      title="添加合同"
      :visible="rentDialogVisible"
      width="580px"
      :close-on-click-modal="false"
      @close="closeDialog()"
    >
      <!-- 表单模版 -->
      <div class="form-container">
        <el-form ref="addForm" :model="rentForm" :rules="rentRules" label-position="top">
          <el-form-item label="租赁楼宇" prop="buildingId">
            <el-select v-model="rentForm.buildingId" placeholder="请选择">
              <el-option
                v-for="item in rentBuildingList"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="租赁起止日期" prop="rentTime">
            <el-date-picker
              v-model="rentForm.rentTime"
              type="daterange"
              range-separator="-"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              value-format="yyyy-MM-dd"
            />
          </el-form-item>
          <el-form-item label="租赁合同" prop="contractId">
            <!-- action 必传，默认上传地址，不需要时使用“#” -->
            <!-- :http-request 覆盖默认上传 -->
            <!-- :before-upload 上传前的钩子 -->
            <!-- :limit 限制上传个数 -->
            <!-- :on-exceed 超出上传限制时执行 -->
            <!-- :on-remove 文件移出时自动执行 -->
            <el-upload
              ref="upload"
              action="#"
              :limit="1"
              :on-exceed="handleExceed"
              :http-request="uploadRent"
              :before-upload="beforeUpload"
              :on-remove="handleRemove"
            >
              <el-button size="small" type="primary" plain>上传合同文件</el-button>
              <div slot="tip" class="el-upload__tip">支持扩展名：.doc .docx .pdf, 文件大小不超过5M</div>
            </el-upload>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <el-button size="mini" @click="closeDialog">取 消</el-button>
        <el-button size="mini" type="primary" @click="confirmAdd()">确 定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import {
  getEnterpriseListAPI,
  deleteEnterpriseAPI,
  getRentBuildingAPI,
  addRentAPI,
  getExpandRentAPI,
  rentingOutAPI,
  rentingDelAPI,
} from "@/api/enterprise";
import { uploadFileAPI } from "@/api/common";
import { mapState } from "vuex";
export default {
  name: "Enterprise",
  data() {
    return {
      params: {
        name: "",
        page: 1,
        pageSize: 2,
      },
      list: [],
      total: 0,
      rentBuildingList: [],
      // 控制添加合同弹框显示隐藏
      rentDialogVisible: false,
      rentForm: {
        buildingId: null,
        startTime: "",
        endTime: "",
        contractUrl: "",
        contractId: null,
        type: 0,
        enterpriseId: null,
        rentTime: [],
      },
      rentRules: {
        buildingId: [{ required: true, message: "请选择楼宇", trigger: "change" }],
        rentTime: [{ required: true, message: "请选择租赁日期", trigger: "change" }],
        contractId: [{ required: true, message: "请上传合同文件", trigger: "change" }],
      },
    };
  },
  computed: {
    // 将状态映射转换为计算属性，避免每次渲染都创建新对象
    statusMap() {
      return {
        0: { text: "待生效", type: "warning" },
        1: { text: "生效中", type: "success" },
        2: { text: "已到期", type: "info" },
        3: { text: "已退租", type: "danger" },
      };
    },
    ...mapState("menu", ["permissions"]),
  },
  created() {
    this.getEnterpriseList();
  },
  methods: {
    // 删除合同
    async rentingDel(id) {
      this.$confirm("您确定删除码？", "温馨提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "info",
      })
        .then(async () => {
          await rentingDelAPI(id);
          this.$message({
            type: "success",
            message: "删除成功!",
          });
          //  遍历企业列表，找到符合条件的企业所在行
          const enterprise = this.list.find((item) =>
            // 根据当前行row.id（合同id）查找被遍历企业的合同列表
            item.rentList.some((rent) => rent.id === id),
          );
          // 找到该企业
          if (enterprise) {
            // 更新该企业的合同列表
            enterprise.rentList = (await getExpandRentAPI(enterprise.id)).data;
          }
        })
        .catch(() => {});
    },
    // 退租
    async rentingOut(id) {
      this.$confirm("您确定退租码？", "温馨提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "info",
      })
        .then(async () => {
          await rentingOutAPI(id);
          this.$message({
            type: "success",
            message: "退租成功!",
          });
          //  遍历企业列表，找到符合条件的企业
          const enterprise = this.list.find((item) =>
            // 根据当前行row.id（合同id）查找被遍历企业的合同列表
            item.rentList.some((rent) => rent.id === id),
          );
          // 找到该企业
          if (enterprise) {
            // 更新该企业的合同列表
            enterprise.rentList = (await getExpandRentAPI(enterprise.id)).data;
          }
        })
        .catch(() => {});
    },
    // 简化状态格式化方法
    formatStatus(status) {
      return this.statusMap[status]?.text || "未知状态";
    },
    formatInfoType(status) {
      return this.statusMap[status]?.type || "";
    },
    // 点击展开或者关闭都会触发
    // row 当前行数据
    // expandChange 所有展开行数据
    async expandChange(row, expandedRows) {
      const isInclude = expandedRows.find((item) => {
        return item.id === row.id;
      });
      if (isInclude) {
        // eslint-disable-next-line require-atomic-updates
        row.rentList = (await getExpandRentAPI(row.id)).data;
      }
    },
    // 提交租赁合同/兜底校验
    confirmAdd() {
      this.$refs.addForm.validate(async (flag) => {
        if (!flag) return;
        const [startTime, endTime] = this.rentForm.rentTime;
        this.rentForm.startTime = startTime;
        this.rentForm.endTime = endTime;
        delete this.rentForm.rentTime;
        await addRentAPI(this.rentForm);
        this.$message.success("添加合同成功");
        // 找到当前企业所在的行
        const enterprise = this.list.find((item) => item.id === this.rentForm.enterpriseId);
        if (enterprise) {
          // 直接调用接口获取最新的合同列表
          enterprise.rentList = (await getExpandRentAPI(this.rentForm.enterpriseId)).data;
        }
        // 关闭弹框
        this.closeDialog();
      });
    },
    // 上传合同
    async uploadRent({ file }) {
      const formData = new FormData();
      formData.append("file", file);
      formData.append("type", 2);
      const { data } = await uploadFileAPI(formData);
      this.rentForm.contractUrl = data.url;
      this.rentForm.contractId = data.id;
      this.$refs.addForm.validateField("contractId");
    },
    // 上传文件校验
    beforeUpload(file) {
      const allowFileType = [
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        "applicatoin/",
        "application/pdf",
      ].includes(file.type);
      const isLt5M = file.size / 1024 / 1024 < 5;
      if (!allowFileType) {
        this.$message.error("上传合同只能是 doc/docx/pdf 格式!");
        return false;
      }
      if (!isLt5M) {
        this.$message.error("上传合同大小不能超过 5MB!");
        return false;
      }
      return allowFileType && isLt5M;
    },
    // 超出上传限制提示
    handleExceed() {
      this.$message.warning(`当前限制选择 1 个文件`);
    },
    // 移出上传文件
    handleRemove() {
      this.rentForm.contractId = null;
      this.rentForm.contractUrl = null;
      this.$refs.addForm.validateField("contractId");
    },
    // 打开弹框/添加合同
    async openAddRent(id) {
      this.rentDialogVisible = true;
      const { data } = await getRentBuildingAPI();
      this.rentBuildingList = data;
      this.rentForm.enterpriseId = id;
    },
    // 关闭弹框/清空数据
    closeDialog() {
      this.rentDialogVisible = false;
      // 只能清空绑定prop的表单域
      this.$refs.addForm.resetFields();
      this.rentForm = {
        buildingId: null,
        startTime: "",
        endTime: "",
        contractUrl: "",
        contractId: null,
        type: 0,
        enterpriseId: null,
        rentTime: [],
      };
      // 移出添加的文件
      this.$refs.upload.clearFiles();
    },
    // 删除企业
    delEnterprise(id) {
      this.$confirm("您确定要删除该企业吗？", "温馨提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          await deleteEnterpriseAPI(id);
          this.$message({
            type: "success",
            message: "删除成功!",
          });
          // 获取列表时已处理，无数据页会自动跳转
          // if (this.list.length === 1 && this.params.page > 1) {
          //   this.params.page--;
          // }
          this.getEnterpriseList();
        })
        // 取消必须写，不然会报错
        .catch(() => {});
    },
    // 编辑企业信息
    editEnterprise(id) {
      this.$router.push({
        path: "/addEnterprise",
        query: {
          id,
        },
      });
    },
    // 获取列表
    async getEnterpriseList() {
      const {
        data: { rows, total },
      } = await getEnterpriseListAPI(this.params);
      // 获取列表 / 并且给列表中每个对象添加rentList列表
      // 以便展开式数据存放（expandChange）
      this.list = rows.map((item) => {
        return { ...item, rentList: [] };
      });
      this.total = total;
      // 当搜索页码超出最大容量时的处理
      const maxPage = Math.ceil(total / this.params.pageSize);
      if (this.params.page > maxPage && maxPage > 0) {
        this.params.page = maxPage;
        this.$message.warning("已自动跳转到最后一页");
        this.getEnterpriseList();
        return;
      }
    },
    // 翻页
    handleCurrentChange(val) {
      this.params.page = val;
      this.getEnterpriseList();
    },
    // 序号计算
    indexMethod(index) {
      return index + 1 + (this.params.page - 1) * this.params.pageSize;
    },
    // 查询/清空搜索
    search() {
      // this.params.page = 1
      // this.getEnterpriseList()
      this.handleCurrentChange(1);
    },
  },
};
</script>

<style lang="scss" scoped>
.department-container {
  padding: 10px;
}

.search-container {
  display: flex;
  align-items: center;
  border-bottom: 1px solid rgb(237, 237, 237, 0.9);
  padding-bottom: 20px;

  .search-label {
    width: 100px;
  }

  .search-main {
    width: 220px;
    margin-right: 10px;
  }
}
.create-container {
  margin: 10px 0px;
}
.page-container {
  padding: 4px 0px;
  text-align: right;
}
.form-container {
  padding: 0px 80px;
}
</style>
